package demo4

// 将一个复杂对象的构建分离成多个简单对象的构建组合
// builder 创建者模式  Director  Construct
// 建造者设计模式
import "fmt"

// 建造者 将复杂的逻辑模块化
type builder interface {
	Part1() // 1
	Part2() // 2
	Part3() // 3
}

// 原有的模块，原有的逻辑 | 结构体来包含上面所有的组合逻辑 | 当然也可以抽象的接口来实现，
// 因为一个复杂的业务逻辑都是已经知道该复杂的业务逻辑的负责具体功能了，所以会用一个具体的实例结构体来包含其中每一块复杂的逻辑
type Director struct{
	builder
}

// 构造方法
func NewDirector(builder builder) *Director{
	return &Director{
		builder:builder,
	}
}

// 调用
func (d *Director)Construct(){
	// 方法实现，组合每一个业务逻辑模块
	d.builder.Part1()
	d.builder.Part2()
	d.builder.Part3()
}

// 模块化后的每一块逻辑业务，分开
// 这里使用的是结构体与上面对应
type built1 struct{ // 该业务逻辑支持横向拓展
	result int
}

// 构造
func NewBuilt() *built1{
	return &built1{}
}

// 方法的规范可以根据业务逻辑的需求来变更
func (b *built1)Part1(){
	// 每一个模块对应的业务逻辑 doSomething
	b.result += 1
}

func (b *built1)Part2(){
	b.result *= 10
}

func (b *built1)Part3(){
	b.result /= 2
}

func (b *built1)Result() int{
	return b.result
}

// --------------------------------场景2-----------------------------------
// 建造者设计模式： 是把一个复杂的业务逻辑模块，分离成多个简单的业务逻辑模块
// 需求： 设计一个递归计算器，支持加减乘除运算，根据用户输入的数据 然后经过 +1 -2 *3 /4 得到结果 
// 第二计算器要求 +4 -3 *2 /1的结果


type calculation interface{
	add()
	subtract()
	multiply()
	divide()
}

type Calculator struct{
	calculation
}

func NewCaclulator(c calculation)*Calculator{
	return &Calculator{
		calculation:c,
	}
}

func (c *Calculator)Construct(){
	c.calculation.add()
	c.calculation.subtract()
	c.calculation.multiply()
	c.calculation.divide()
}
// 第一个计算
type calc_1 struct{
	sum int
}
func NewCalc_1() *calc_1{
	return &calc_1{}
}
func (c *calc_1)add(){ c.sum += 10 }
func (c *calc_1)subtract(){ c.sum -= 2 }
func (c *calc_1)multiply(){ c.sum *= 3 }
func (c *calc_1)divide(){ c.sum /= 4 }
func (c *calc_1)GetResult() int { return c.sum }


// --------------------------------场景3-----------------------------------

// 需求：用户的登录
// DDD分析： 用户登录之前的参数校验，用户登录成功之后的签名发放，用户成功之后的页面跳转
// 细节分析： 参数校验paramCheck() 用户登录状态保持JWTCreate()|存储位置到Redis()实现状态保持, 用户登录成功之后的业务跳转Redirect()
// Login 

type register interface{
	paramCheck(username, password string) bool
	jwtCreate() bool
	statusStorage(choice int) bool
	pageRedirect() bool
}

type login struct{
	register
}

func NewLogin(r register) *login{
	return &login{
		register:r,
	}
}

// 这里可以加上一些逻辑判断 
func (o *login) Construct(username, password string,choice int) bool{
	if !o.register.paramCheck(username,password) 	{ return false }
	if !o.register.jwtCreate() 	{ return false }
	if !o.register.statusStorage(choice) 	{ return false }
	if !o.register.pageRedirect() 	{ return false }
	return true
}

// 某个用户的登录验证
type user struct{
	legitimate bool  // 可以用于判断结果
}

func NewUser() *user{
	return &user{legitimate:true}
}

// 可以传入一些参数 登录校验的账户和密码
func (u *user)paramCheck(username, password string) bool{
	fmt.Println("参数校验中......")
	if username != "小猪" || password != "123"{
		u.legitimate = false
		fmt.Println("参数校验失败......")
		return false
	}
	fmt.Println("-------参数校验成功--------")
	return true
}
func (u *user)jwtCreate()bool{
	// do-semothing
	u.legitimate = true
	return true
	// do-semothing
}
func (u *user)statusStorage(choice int) bool{
	fmt.Println("签名存储选择中....")
	switch choice {
	case 1:
		fmt.Println("redis存储......")
		return true
	case 2:
		fmt.Println("db存储......")
		return true
	case 3:
		fmt.Println("redis存储......")
		return true
	default:
		fmt.Println("存储失败......")
		u.legitimate = false
		return false
	}
}

func (u *user)pageRedirect() bool{
	// do-something
	u.legitimate = true
	return true
	// do something
}

func (u *user)GetResult(){
	if u.legitimate{
		fmt.Println("登录成功.....")
		fmt.Println("正在获取个人信息.....")
		fmt.Println("个人信息如下:")
		return
	}
	fmt.Println("登录失败.....")

	// do something ----
}

// --------------------------------场景4-----------------------------------
// 建造者设计模式运用的场景较多，很多地方都能用到，关于到一个类方法较多的时候可以进行拆分，
// 优点就是支持拓展性，
// 举例，比如说用户会员等级划分，不同等级对应不同的方法和属性，当然模板设计也可以
// 或者  说一个业务逻辑比较复杂的功能，更加偏向于一些细节逻辑的实现 支付====>支付宝支付[金额，金额验证，用户验证，用户身份校验，用户金额充足校验，用户支付结果等等]
// 偏向一某个实例对象内部的实现，再比如一辆汽车===>车[发动机，油门，离合器，刹车，仪表盘，中控....]内部对应零件功能的运作实现
// 当然像汽车===>发动机，对于发动机的角度来说，发动机可能就是一个实例，位置不同可能会有不同的理解，那么发动机的原理可能就是复杂的实现过程
// 而复杂的实现过程就是对应着的每一块业务逻辑，相对工厂 ，工厂更偏向于实例的构建，而建造者更偏于实例内部的业务实现